﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;

namespace FDCopyFile
{
	/*
	CreatedBy: Jackie Lee(天宇遊龍)
	CreatedOn: 2018-01-20
	*/
    class Program
    {
        static void Main(string[] args)
        {
            AGAIN:
            Output("*********************************");
            Output(@"D:\Abc");
            Output(@"*.jpg *.png");
            Output(@"D:\Abc\Result");
            Output("*********************************");
            Output("input the source path:", false);
            SOURCE:
            var source = Console.ReadLine();
            if (source.IsNullOrEmpty())
            {
                Output("please input the true source path:", false);
                goto SOURCE;
            }
            Output("input the file type like \"*.jpg\"(for the jpg file) or \"*.*\"(for all the types) type and type split by \" \"(white space):", false);
            TYPES:
            var type = Console.ReadLine();
            if (type.IsNullOrEmpty())
            {
                Output("please input the file type to copy:", false);
                goto TYPES;
            }
            Output("input the target path(empty for the current path):", false);
            TARGET:
            var target = Console.ReadLine();
            if (target.IsNullOrEmpty())
            {
                target = "./";
            }
            if (!target.IsDirectory())
            {
                Output("please input the exist directory for the target:", false);
                goto TARGET;
            }
            var types = type.Split(' ', StringSplitOptions.RemoveEmptyEntries);
            if (types.Length == 0)
            {
                Output("the type input error.");
                goto AGAIN;
            }
            var trueTypes = types.Select(t =>
            {
                if (t.Length > 1)
                    t = t.Remove(0, 1);
                return t;
            });
            if (trueTypes.Count() == 0)
            {
                Output("the type input error.");
                goto AGAIN;
            }
            var files = Directory.GetFiles(source, ".", SearchOption.AllDirectories);
            if (files.Length == 0)
            {
                Output("there is not any files in the source path.");
                goto AGAIN;
            }
            Copy(files.ToList(), trueTypes, target);
            Output("try again?(Y/n):", false);
            var res = Console.ReadLine();
            if (res.IsNullOrEmpty() || "Y".Equals(res, StringComparison.OrdinalIgnoreCase) || "Yes".Equals(res, StringComparison.OrdinalIgnoreCase))
            {
                goto AGAIN;
            }
            fileIndex = 0;
            Output("Byte!");
        }

        private static void Copy(List<string> source, IEnumerable<string> trueTypes, string target)
        {
            var result = new List<string>();
            int len = 0;
            Output("Copy the files ...");
            foreach (var file in source)
            {
                var ext = Path.GetExtension(file);
                if (trueTypes.Contains(ext))
                {
                    if (Copying(file, target))
                        len++;
                }
            }
            Output($"successfully copy {len} files to {target}");
        }

        private static void Output(string str, bool bReturn = true)
        {
            if (bReturn)
                Console.WriteLine(str);
            else
                Console.Write(str);
        }

        static int fileIndex = 0;

        static Func<string, string> FilePreName = file =>
         {
             return $"{Path.GetDirectoryName(file)}_";
         };

        private static bool Copying(string file, string target)
        {
            try
            {
                string fileName = Path.Combine(target, Path.GetFileName(file));
                CHECKFILE:
                if (File.Exists(fileName))
                {
                    fileName = Path.Combine(target, $"{Path.GetFileNameWithoutExtension(file)}{fileIndex}{Path.GetExtension(file)}");
                    fileIndex++;
                    goto CHECKFILE;
                }
                File.Copy(file, fileName, true);
                return true;
            }
            catch (Exception ex)
            {
                Output($"there is an error on copying the \"{file}\":{ex.Message}");
                return false;
            }
        }
    }

    static class Extension
    {
        public static bool IsNullOrEmpty(this string str)
        {
            return string.IsNullOrEmpty(str) || str.Trim().Length == 0;
        }

        public static bool IsDirectory(this string str)
        {
            return !str.IsNullOrEmpty() && Directory.Exists(str);
        }
    }
}
